<?php
declare (strict_types = 1);

namespace app\controller\admin;

use app\model\Goods;
use app\model\GoodsItem;
use app\model\GoodsSpec;
use think\facade\Db;
use think\facade\Validate;
use think\response\Json;

class AdminGoods extends AdminBase
{

	protected $middleware = [
		'app\middleware\AdminLogin',
		'app\middleware\AdminAuth'
	];

	private $menuName = '商品管理';

    /**
     * 显示资源列表
     * @throws
     * @return Json
     */
    public function index():Json
    {
        $limit = input('pageSize/d',10);

		//分页配置
		$pageConfig = ['list_rows'=>$limit,'var_page'=>'pageNum'];

        $field = 'id,id as value,name as label';
        $classify = Db::name('goods_classify')
            ->field($field)
            ->where('parent_id',0)
            ->where('status',1)
            ->select()->toArray();
        $this->nextList($classify,'goods_classify',[['status','=',1]],['sort'=>'asc'],'children','parent_id','id',$field);

		//搜索字段配置
        $search = [
			[
				'label'=>'商品名称',//标签
				'prop'=> 'name',//表单名称
				'field' => 'goods_name',//查询字段
				'placeholder'=> '模糊搜索名称',
				'required'=> false,//是否必填
				'expression' => 'like',//查询表达式：like,not like,in,not in,between,not between,null,not null,time,>,<,>=,<=,=,<>(!=),find(FIND_IN_SET)
				'type'=> 'input',//类型：input,select,cascader,date,datetime,year,month,week,datetimerange,daterange
                'typeof' => 's',//强制转换类型：d整数，a数组，s字符串，b布尔类型，f浮点数
			],
            [
                'label'=>'所属分类',//标签
                'prop'=> 'gid',//表单名称
                'field' => 'goods_classify_id',//查询字段
                'placeholder'=> '选择分类',
                'required'=> false,//是否必填
                'expression' => '=',//查询表达式：like,not like,in,not in,between,not between,null,not null,time,>,<,>=,<=,=,<>(!=),find(FIND_IN_SET)
                'type'=> 'cascader',//类型：input,select,cascader,date,datetime,year,month,week,datetimerange,daterange
                'typeof' => 'd',//强制转换类型：d整数，a数组，s字符串，b布尔类型，f浮点数
                'options' => $classify
            ],
		];

		$map = [];
		$this->setMap($search,$map);

		$data = Goods::with(['c'])
            ->where($map)
			->order('create_time','desc')
			->paginate($pageConfig);

		$this->result['data'] = [
			'total' => $data->total(),
			'data' => $data->items(),
			'search' => $search,
            'classify' => $classify
		];
		return returnAdmin($this->request,$this->result,$this->menuName.'-列表',$this->adminInfo);
    }

    /**
	 * 保存编辑的资源
	 * @throws
	 * @return Json
	 */
	public function save():Json
	{
		//获取form表单
		$param = input('param.',[]);

		$param = toUnderline($param);

		try{

			$model = new Goods();
			$fields = $model->getFields();
			$pk = $model->getPk();
			$id = $param[$pk] ?? 0;
			$rule = [
				'goods_name' => 'require|max:255',
				//'price' => 'require|number',
				'goods_classify_id' => 'require',
			];
			$message = [
				'goods_name.require' => '商品名称必填',
				'goods_name.max' => '商品名称最多255个字符',
				'price.require' => '售价必填',
				'price.max' => '售价只能填写数字',
				'goods_classify_id' => '分类必选'
			];
			$validate = Validate::rule($rule)->message($message);

			if(!$validate->check($param)){
				throw new \Exception($validate->getError());
			}

            $param['status'] = $param['status'] ?? 0;//防止开关不传值

			if(!$id){
				//新增
				$info = $model->create($param,$fields);
                $info->dt()->save(['detail'=>$param['detail']??'']);//保存详情
                $id = $info->id;
			}else{
				//修改
				$info = $model->find($id);
				if(!$info){
					throw new \Exception('无效参数');
				}

				$info->allowField($fields)->save($param);
                $info->dt()->save(['detail'=>$param['detail']??'']);//保存详情
			}

            //处理参数
            $params = [];
            $oldIDS = [];
            if(isset($param['param']) && is_array($param['param']) && count($param['param'])){
                foreach ($param['param'] as $k => $p){
                    $name = $p['name'] ?? '';
                    $value = $p['value'] ?? '';
                    if($name && $value){
                        $pid = $p['id'] ?? 0;
                        if($pid){
                            Db::name('goods_param')
                                ->where('id',$pid)
                                ->update([
                                    'name' => $name,
                                    'value' => $value,
                                    'sort' => $p['sort'] ?? $k
                                ]);
                            $oldIDS[] = $pid;
                        }else{
                            //插入
                            $params[] = [
                                'goods_id' => $id,
                                'name' => $name,
                                'value' => $value,
                                'sort' => $p['sort'] ?? $k
                            ];
                        }

                    }
                }
            }
            //删除旧的参数
            if(count($oldIDS)){
                Db::name('goods_param')
                    ->whereNotIn('id',$oldIDS)
                    ->delete();
            }else{
                Db::name('goods_param')
                    ->where('goods_id',$id)
                    ->delete();
            }
            //插入新的记录
            if(count($params)){
                Db::name('goods_param')->insertAll($params);
            }
            //处理规格
            $goods_specs = [];
            if(isset($param['spec']) && is_array($param['spec']) && count($param['spec'])) {
                foreach ($param['spec'] as $spec){
                    $name = trim($spec['name'] ?? '');
                    $value = $spec['value'] ?? [];
                    if(!$name || !is_array($value) || !count($value)){
                        continue;
                    }
                    $va = 0;
                    foreach ($value as $v) {
                        $val = $v['value'] ?? '';
                        if (!$val) {
                            continue;
                        }
                        $va += 1;
                    }
                    if(!$va){
                        continue;
                    }
                    $goods_specs[] = $spec;
                }
                $new_spec_name_ids = [];
                if(count($goods_specs)){
                    foreach ($goods_specs as $sn) {
                        $name = trim($sn['name'] ?? '');
                        $value = $sn['value'] ?? [];
                        $sid = intval($sn['id'] ?? 0);
                        if($sid) {
                            //更新规格名
                            Db::name('goods_spec')
                                ->where('id', $sid)
                                ->update(['name' => $name]);
                        } else {
                            //添加规格名
                            $sid = Db::name('goods_spec')
                                ->insertGetId(['goods_id' => $id, 'name' => $name]);
                        }
                        $new_spec_name_ids[] = $sid;

                        //处理规格值
                        $new_spec_value_ids = [];
                        foreach ($value as $k => $v) {
                            $vid = $v['id'] ?? 0;
                            $val = $v['value'] ?? '';
                            if(!$val){
                                continue;
                            }
                            $temp = [
                                'goods_id' => $id,
                                'spec_id' => $sid,
                                'value' => $val,
                            ];
                            if ($vid) {
                                //更新规格值
                                Db::name('goods_spec_value')
                                    ->where('id' , $vid)
                                    ->update($temp);
                            } else {
                                //添加规格值
                                $vid = Db::name('goods_spec_value')
                                    ->insertGetId($temp);
                            }
                            $new_spec_value_ids[] = $vid;
                        }
                        $all_spec_value_ids = Db::name('goods_spec_value')
                            ->where('spec_id', $sid)
                            ->column('id');
                        $del_spec_value_ids = array_diff($all_spec_value_ids, $new_spec_value_ids);
                        if (!empty($del_spec_value_ids)) {
                            //删除规格值
                            Db::name('goods_spec_value')
                                ->where('spec_id', $sid)
                                ->where('id', 'in', $del_spec_value_ids)
                                ->delete();
                        }
                    }
                }else{
                    //删除规格值
                    Db::name('goods_spec_value')
                        ->where('goods_id', $id)
                        ->delete();
                }
                //删除规格名
                $all_spec_ids = Db::name('goods_spec')
                    ->where('goods_id', $id)
                    ->column('id');
                $del_spec_name_ids = array_diff($all_spec_ids, $new_spec_name_ids);
                if (!empty($del_spec_name_ids)) {
                    Db::name('goods_spec')
                        ->where('goods_id', $id)
                        ->where('id', 'in', $del_spec_name_ids)
                        ->delete();
                }
            }

            //处理规格明细
            if(isset($param['items']) && is_array($param['items']) && count($param['items']) && count($goods_specs)){
                $spec_lists = $param['items'];
                $new_item_id = [];

                $goods_spec_name_value_id = Db::name('goods_spec_value')
                    ->where('goods_id' , $id)
                    ->column('id', 'value');
                foreach ($spec_lists as $v) {

                    $ids = $v['ids'] ?? '';
                    if(!$ids){
                        $strArr = explode(',', $v['value']);
                        $ids_arr = [];
                        foreach ($strArr as $sv) {
                            $ids_arr[] = $goods_spec_name_value_id[$sv] ;
                        }
                        $ids = implode(',',$ids_arr);
                    }

                    $temp = [
                        'goods_id' => $id,
                        'logo' => $v['logo'] ?? '',
                        'spec_value_str' => $v['value'] ?? '',
                        'line_price' => $v['line_price'] ?? 0,
                        'price' => $v['price'] ?? 0,
                        'sku' => $v['sku'] ?? 0,
                        'spec_value_ids' => $ids
                    ];

                    $item_id = $v['id'] ?? 0;
                    if ($item_id) {
                        Db::name('goods_item')
                            ->where('id', $item_id)
                            ->update($temp);
                    } else {
                        $item_id = Db::name('goods_item')
                            ->insertGetId($temp);
                    }
                    $new_item_id[] = $item_id;
                }

                $all_item_id = Db::name('goods_item')
                    ->where('goods_id', $id)
                    ->column('id');
                $del_item_ids = array_diff($all_item_id, $new_item_id);
                if (!empty($del_item_ids)) {
                    //删除规格值
                    Db::name('goods_item')
                        ->where('goods_id', $id)
                        ->where('id', 'in', $del_item_ids)
                        ->delete();
                }
            }else{
                //删除规格值
                Db::name('goods_item')
                    ->where('goods_id', $id)
                    ->delete();
            }

		}catch (\Exception $e){
			$this->result['code'] = 500;
			$this->result['msg'] = $e->getMessage();
		}
		return returnAdmin($this->request,$this->result,$this->menuName.'-编辑',$this->adminInfo);
	}

    /**
     * 删除指定资源
     * @throws
     * @return Json
     */
    public function delete():Json
    {

        $id = (string) input('id','');
        $ids = explode(',',$id);
		try {
			//批量删除
			if (count($ids) > 1) {
				Goods::destroy($ids);
			} else {
			//指定id删除
				$info = Goods::find($id);
				if (!$info) {
					throw new \Exception('无效参数');
				}
				$info->delete();
				//其他处理
			}
			$this->result['msg'] = '删除ID：'.$id;
		}catch (\Exception $e){
			$this->result['code'] = 500;
			$this->result['msg'] = $e->getMessage();
		}

        return returnAdmin($this->request,$this->result,$this->menuName.'-删除',$this->adminInfo);
    }

    /**
     * 获取详情
     *
     * @throws
     * @return Json
     * */
    public function detail():Json
    {
        $id = input('id/d',);

        //详情
        $detail = Db::name('goods_detail')
            ->where('goods_id',$id)
            ->value('detail','');

        //商品参数
        $params = Db::name('goods_param')
            ->field('name,value,sort')
            ->where('goods_id',$id)
            ->order('sort')
            ->select()->toArray();

        if(!count($params)){
            $params = [['name'=>'','value'=>'','sort'=>0,'id'=>0]];
        }

        //商品规格
        $spec = GoodsSpec::with(['child'])
            ->where('goods_id',$id)
            ->select()
            ->each(function($item){
                $item['value'] = $item['child'];
                unset($item['child']);
                return $item;
            })
            ->toArray();

        //规格明细
        $items = GoodsItem::where('goods_id',$id)
            ->select()->toArray();

        if(count($items)){
            $tem_items = [];
            foreach ($items as $item){
                $tem_item = [
                    'id' => $item['id'],
                    'logo' => $item['logo'],
                    'line_price' => $item['line_price'],
                    'price' => $item['price'],
                    'sku' => $item['sku'],
                    'value' => $item['spec_value_str'],
                    'ids' => $item['spec_value_ids'],
                ];
                $svs = explode(',',$item['spec_value_str']);
                foreach ($svs as $k=>$sv){
                    $tem_item['sv'.$k] = $sv;
                }
                $tem_items[] = $tem_item;
            }
            $items = $tem_items;
        }

        $this->result['data'] = [
            'detail' => $detail,
            'param' => $params,
            'spec' => $spec,
            'items' => $items
        ];

        return jJson($this->result);
    }


}
